﻿/******************************************************************************
 * Name			: Player.cpp
 * Author		: 671643387
 * Date			: 2015年9月13日
 * Description	:
 *****************************************************************************/

#include <boost/bind.hpp>
#include "../packet/PacketFactoryManager.hpp"
#include "Player.hpp"
using namespace sxr::common;

Player::Player(int id, dev::net::TcpConnectionPtr& conn)
: id_(id)
, conn_(conn)
{
    // 绑定连接和Player
    conn->setMessageCallback(boost::bind(&Player::onMessage, this, _1, _2));
    conn->setErrorCallback(boost::bind(&Player::onConnectionError, this, _1));
    conn->setClosingCallback(boost::bind(&Player::onConnectionClosing, this, _1));
    conn->setHeartBeatCallback(boost::bind(&Player::onConnectionHeartBeat, this, _1));
    conn->setWritableCallback(boost::bind(&Player::onConnectionWritable, this, _1));
}

Player::~Player()
{

}

bool Player::executePacket(PacketPtr packet)
{
    return packet->execute(this);
}

void Player::sendPacket(PacketPtr packet)
{
    // 将包加入到队列
    sendPackets_.push_back(packet);
}

void Player::onHeartbeat()
{
    // TODO:
}

///////////////////////////////////////////////////////////////////////////////
void Player::onConnectionError(dev::net::TcpConnection& conn)
{
}
void Player::onConnectionClosing(dev::net::TcpConnection& conn)
{
    onRemovePlayer();
}
void Player::onConnectionHeartBeat(dev::net::TcpConnection& conn)
{
    onHeartbeat();
}

void Player::onConnectionWritable(dev::net::TcpConnection& conn)
{
    dev::net::TcpConnectionOutputStream& os = conn.getOutputStream();

    while (!sendPackets_.empty())
    {
        // 取队列头的包
        PacketPtr packet = sendPackets_.front();

        // 写包
        packet->write(os);

        // 判断这个包是否已经全部写到流，如果是从队列移除
        if (packet->empty())
        {
            sendPackets_.pop_front();
        }

        // 流已经写满了
        if (os.space() <= 0)
            break;
    }
}

void Player::onMessage(dev::net::TcpConnection& conn, dev::net::TcpConnectionInputStream& is)
{
    struct Packet::_stHead pktHead;

    do 
    {
        if (!Packet::canReadPacket(is, pktHead))
        {
            break;
        }

        // 创建对应的数据包
        PacketPtr packet = PacketFactoryManager::getMe()->createPacket(pktHead.id);
        if (!packet)
        {
            // TODO: 创建数据包失败
            break;
        }

        // 读数据
        if (!packet->read(is))
        {
            break;
        }

        // 执行包
        if (!executePacket(packet))
        {
            // TODO: 执行包失败
        }

    } while (false);
}